package com.ethink.order.manager;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.db.ds.DSFactory;
import cn.hutool.setting.Setting;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.order.api.enums.PurchaseReturnOrderReturnTypeEnum;
import com.ethink.order.api.model.PurchaseDetailModel;
import com.ethink.order.api.model.PurchaseOrderWithPayModel;
import com.ethink.order.common.entity.PurchaseReturnDetailOrder;
import com.ethink.order.common.entity.PurchaseReturnOrder;
import com.ethink.order.common.mapper.PurchaseOrderMapper;
import com.ethink.order.common.mapper.PurchaseReturnOrderMapper;
import com.ethink.order.common.properties.OrderCommonProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class OaPayManager {

    @Autowired
    private OrderCommonProperties commonProperties;

    private static Map<String, String> currencyMap = new HashMap<>();

    @Autowired
    private PurchaseOrderMapper purchaseOrderMapper;

    private DSFactory dsFactory;

    static {
        currencyMap.put("CNY", "1");
        currencyMap.put("EUR", "2");
        currencyMap.put("USD", "3");
        currencyMap.put("HKD", "4");
        currencyMap.put("THB", "5");
        currencyMap.put("SGD", "6");
    }

    public void insert(PurchaseOrderWithPayModel purchaseOrderInfo, List<PurchaseDetailModel> purchaseOrderDetailInfoList) {
        long ct = 0;
        try {
            ct = Db.use(dsFactory.getDataSource()).count("select * from uf_t_purchase_order where order_no = ?", purchaseOrderInfo.getOrderNo());
        } catch (SQLException e) {
            log.error("oa付款记录查询失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "oa付款记录查询失败");
        }
        if(ct > 0) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "已创建OA付款记录，不能重复提交");
        }
        String channel = purchaseOrderInfo.getSaleChannel();
        if (StringUtils.isNotBlank(purchaseOrderInfo.getSaleSubChannel())) {
            channel += "/" + purchaseOrderMapper.getSaleSubChannelName(purchaseOrderInfo.getSaleSubChannel());
        }
        Entity purchaseEntity = Entity.create("uf_t_purchase_order")
                .set("t_id", purchaseOrderInfo.getId())
                .set("formmodeid", commonProperties.getOaFormmodeid())
                .set("order_no", purchaseOrderInfo.getOrderNo())
                .set("oa_status", 1)
                .set("supplier_code", purchaseOrderInfo.getSupplierCode())
                .set("supplier_name", purchaseOrderInfo.getSupplierName())
                .set("out_order_no", purchaseOrderInfo.getOutOrderNo())
                .set("create_user_code", purchaseOrderInfo.getCreateUserCode())
                .set("create_user_name", purchaseOrderInfo.getCreateUserName())
                .set("currency_code", purchaseOrderInfo.getCurrencyCode())
                .set("currency_name", purchaseOrderInfo.getCurrencyName())
                .set("exchange_rate", purchaseOrderInfo.getExchangeRate())
                .set("remark", purchaseOrderInfo.getRemark())
                .set("channel", channel)
                .set("order_price", purchaseOrderInfo.getOrderPrice())
                .set("wfje", purchaseOrderInfo.getOrderPrice());
        List<Entity> purchaseDetailEntityList = new ArrayList<>();
        for (PurchaseDetailModel purchaseOrderDetailInfo : purchaseOrderDetailInfoList) {
            // 销售价，毛利需要计算
            BigDecimal salePrice = purchaseOrderDetailInfo.getExceptSalePriceNoTax();
            BigDecimal grossProfit = purchaseOrderDetailInfo.getExceptGrossProfit();
            Entity purchaseDetailEntity = Entity.create("uf_t_purchase_order_dt1")
                    .set("t_id", purchaseOrderDetailInfo.getId())
                    .set("mate_sku", purchaseOrderDetailInfo.getMateSku())
                    .set("mate_sku_name", purchaseOrderDetailInfo.getMateSkuName())
                    .set("purchase_price", purchaseOrderDetailInfo.getPurchasePrice())
                    .set("lock_order_qty", purchaseOrderDetailInfo.getLockOrderQty())
                    .set("sale_price", salePrice)
                    .set("gross_profit", grossProfit.setScale(2, RoundingMode.HALF_UP).toString() + "%")
                    .set("order_no", purchaseOrderDetailInfo.getOrderNo())
                    .set("currency_code", purchaseOrderDetailInfo.getSaleCurrencyCode())
                    .set("currency_name", purchaseOrderDetailInfo.getSaleCurrencyName());
            purchaseDetailEntityList.add(purchaseDetailEntity);
        }
        Session session = Session.create(dsFactory.getDataSource());
        try {
            session.beginTransaction();
            session.insert(purchaseEntity);
            Entity main = Db.use(dsFactory.getDataSource()).queryOne("select * from uf_t_purchase_order where order_no = ?", purchaseOrderInfo.getOrderNo());
            for (Entity purchaseDetailEntity : purchaseDetailEntityList) {
                purchaseDetailEntity.set("mainid", main.get("id"));
                session.insert(purchaseDetailEntity);
            }
            session.commit();
        } catch (SQLException e) {
            session.quietRollback();
            log.error("数据插入失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA付款数据插入失败");
        }
    }

    public Boolean getAoDone(String orderNo) {
        try {
            List<Entity> result = Db.use(dsFactory.getDataSource()).query("select * from uf_t_purchase_order where order_no = ?", orderNo);
            if (CollectionUtils.isEmpty(result)) {
                return false;
            }
            Entity purchaseEntity = result.get(0);
            Integer oaStatus = purchaseEntity.getInt("oa_status");
            return oaStatus != null && oaStatus != 1;
        } catch (SQLException e) {
            log.error("OA抵扣数据查询失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA付款数据查询失败");
        }
    }

    public void deleteAoPay(String orderNo) {
        try {
            List<Entity> result = Db.use(dsFactory.getDataSource()).query("select * from uf_t_purchase_order where order_no = ?", orderNo);
            if (CollectionUtils.isEmpty(result)) {
                return;
            }
            Entity purchaseEntity = result.get(0);
            Integer oaStatus = purchaseEntity.getInt("oa_status");
            if (oaStatus != null && oaStatus != 1) {
                throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA付款流程已开启不能删除");
            }
            Db.use(dsFactory.getDataSource()).execute("delete from uf_t_purchase_order where order_no = ?", orderNo);
            Db.use(dsFactory.getDataSource()).execute("delete from uf_t_purchase_order_dt1 where mainid = ?", purchaseEntity.get("id"));
        } catch (SQLException e) {
            log.error("OA抵扣数据删除失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA付款数据删除失败");
        }
    }

    @PostConstruct
    public void init() {
        Setting setting = Setting.create();
        setting.set("url", commonProperties.getOaDbUrl());
        setting.set("user", commonProperties.getOaDbUsername());
        setting.set("pass", commonProperties.getOaDbPassword());
        // 是否在日志中显示执行的SQL
        setting.set("showSql", "true");
        // 是否格式化显示的SQL
        setting.set("formatSql", "true");
        // 是否显示SQL参数
        setting.set("showParams", "true");
        // 打印SQL的日志等级，默认debug，可以是info、warn、error
        setting.set("sqlLevel", "debug");
        this.dsFactory = DSFactory.create(setting);
    }

    public void returnInsert(PurchaseOrderWithPayModel purchaseOrderInfo,
                             List<PurchaseDetailModel> purchaseOrderDetailInfoList,
                             PurchaseReturnOrder purchaseReturnOrder,
                             List<PurchaseReturnDetailOrder> purchaseReturnDetailOrderList) {
        Map<String, PurchaseDetailModel> purchaseDetailModelMap
                = purchaseOrderDetailInfoList.stream().collect(Collectors.toMap(PurchaseDetailModel::getDetailOrderNo, info -> info));
        String channel = purchaseOrderInfo.getSaleChannel();
        if (StringUtils.isNotBlank(purchaseOrderInfo.getSaleSubChannel())) {
            channel += "/" + purchaseOrderMapper.getSaleSubChannelName(purchaseOrderInfo.getSaleSubChannel());
        }
        Entity channelEntity;
        try {
            List<Entity> result = Db.use(dsFactory.getDataSource()).query("select * from uf_mzqddcbzx where jkyqd = ?", channel);
            channelEntity = result.get(0);
        } catch (Exception e) {
            log.error("OA抵扣数据创建失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA抵扣数据创建失败");
        }
        Entity supplierEntity;
        try {
            List<Entity> result = Db.use(dsFactory.getDataSource()).query("select * from uf_Provider where gysbm = ?", purchaseOrderInfo.getSupplierCode());
            supplierEntity = result.get(0);
        } catch (Exception e) {
            log.error("OA抵扣数据创建失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA抵扣数据创建失败");
        }
        List<Entity> entityList = new ArrayList<>();
        for (PurchaseReturnDetailOrder returnDetailOrder : purchaseReturnDetailOrderList) {
            PurchaseDetailModel purchaseDetailModel = purchaseDetailModelMap.get(returnDetailOrder.getPurchaseDetailOrderNo());
            Entity purchaseEntity = Entity.create("uf_mzpfdjtz");
//        wbdh  外部单号
//        ycgqd  原采购渠道  联查表(uf_mzqddcbzx.jkyqd) 取id
//        sku    sku
//        sl    数量
//        pfzje  赔付总金额
//        bz    币种（  'CNY': 1,'EUR': 2,'USD': 3,'HKD': 4,'THB': 5,'SGD': 6
//        ydkje  已抵扣金额(默认0
//        gys    供应商（查供应商主表（uf_Provider（gysbm 字段）取id
//        pfsm  赔付说明
//        hl    汇率  字符串
//        ywzz  业务组织  主键id
//            cbzx  成本中心    联查表(uf_mzqddcbzx.jkyqd) 取cbzx
//            lrzx  利润中心    联查表(uf_mzqddcbzx.jkyqd) 取lrzx
//            cbzxbm  成本中心编码  联查表(uf_mzqddcbzx.jkyqd) 取cbzxbm
//            lrzxbm  利润中心编码  联查表(uf_mzqddcbzx.jkyqd) 取lrzxbm
//            ddlx  订单类型    采购单-少货==0,采购退货==1
//            formmodeid    114
            //ab    默认=1
                    purchaseEntity
                    .set("wbdh", purchaseOrderInfo.getOutOrderNo())
                    .set("cgdh", purchaseDetailModel.getOrderNo())
                    .set("ycgqd", channelEntity.get("id"))
                    .set("sku", purchaseDetailModel.getMateSku())
                    .set("sl", returnDetailOrder.getLessQty())
                    .set("pfzje", purchaseDetailModel.getPurchasePrice().multiply(new BigDecimal(returnDetailOrder.getLessQty())))
                    .set("bz", currencyMap.get(purchaseOrderInfo.getCurrencyCode()))
                    .set("ydkje", 0)
                    .set("gys", supplierEntity.get("id"))
                    .set("pfsm", "")
                    .set("hl", purchaseOrderInfo.getExchangeRate())
//                    .set("ywzz", 0)
                    .set("cbzx", channelEntity.get("cbzx"))
                    .set("lrzx", channelEntity.get("lrzx"))
                    .set("cbzxbm", channelEntity.get("cbzxbm"))
                    .set("lrzxbm", channelEntity.get("lrzxbm"))
//                    .set("ddlx", PurchaseReturnOrderReturnTypeEnum.S1.eq(purchaseReturnOrder.getReturnType()) ? "0" : "1")
                    .set("formmodeid", "114")
                    .set("ab", "1");
            entityList.add(purchaseEntity);
        }
        Session session = Session.create(dsFactory.getDataSource());
        try {
            session.beginTransaction();
            for (Entity entity : entityList) {
                session.insert(entity);
            }
            session.commit();
        } catch (SQLException e) {
            session.quietRollback();
            log.error("数据插入失败", e);
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "OA抵扣数据插入失败");
        }
    }
}
